package com.telit.firecommand.controller;

import cn.hutool.core.util.StrUtil;
import com.alibaba.fastjson.JSON;
import com.telit.common.constant.Constant;
import com.telit.common.entity.DataReturn;
import com.telit.common.entity.PageData;
import com.telit.common.enums.ResultCode;
import com.telit.common.util.RedisUtils;
import com.telit.firecommand.constant.RedisKeyConstant;
import com.telit.firecommand.dto.CameraFirePointDTO;
import com.telit.firecommand.dto.DistrictCountDTO;
import com.telit.firecommand.entity.CommCameraInfo;
import com.telit.firecommand.model.camera.QryDistrictListByCodesRequest;
import com.telit.firecommand.service.CameraInfoService;
import com.telit.firecommand.service.CameraMonitorService;
import com.telit.firecommand.vo.CameraVO;
import com.telit.firecommand.vo.FirePointResourceVO;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import java.util.ArrayList;
import java.util.List;


/**
 * @Author:zhangwei
 * @Description:
 * @Time:Created on 2022/8/30 18:10
 */
@Slf4j
@RestController
@RequestMapping("/camera-info")
@Api(tags = "监控设备信息处理接口", description = "camera-info")
public class CameraInfoController {

    @Autowired
    private CameraMonitorService cameraMonitorService;

    @Autowired
    private CameraInfoService cameraInfoService;


    @PostMapping("/cacheCameraPosition")
    @ApiOperation(value = "缓存监控设备用于首页展示", httpMethod = Constant.REQUEST_METHOD_POST)
    public DataReturn cacheCameraPosition(@RequestBody List<CameraVO> voList,
                                          @RequestParam(value = "districtCode") String districtCode) {
        try {
            if (voList == null || districtCode == null) {
                return DataReturn.failure(ResultCode.FORM_PARAMS_CHECK_ERROR);
            }
            RedisUtils.set(RedisKeyConstant.CAMERA_POSITION + districtCode, JSON.toJSONString(voList));
            return DataReturn.ok();
        } catch (Exception e) {
            e.printStackTrace();
            return DataReturn.failure();
        }
    }

    @ApiImplicitParams({
            @ApiImplicitParam(name = "districtCode", value = "行政区划", required = true, paramType = "query", dataType = "String"),
    })
    @GetMapping("/getCameraPosition")
    @ApiOperation(value = "获取首页展示监控设备", httpMethod = Constant.REQUEST_METHOD_GET)
    public DataReturn<List<CameraVO>> getCameraPosition(@RequestParam(value = "districtCode") String districtCode) {
        try {

            List<CameraVO> voList = cameraInfoService.getCameraPosition(districtCode);
            List<CameraVO> effectiveList = new ArrayList<>();
            for (CameraVO object : voList) {
//                String previewUrl = RedisUtils.get(RedisKeyConstant.CAMERA_PREVIEW_URL + object.getCode());
//                if (StrUtil.isEmpty(previewUrl)) {
//                    //获取并缓存
//                    try {
//                        previewUrl = cameraMonitorService.queryFlvpUrl(object.getCode());
//                        if (StrUtil.isNotEmpty(previewUrl)) {
//                            RedisUtils.set(RedisKeyConstant.CAMERA_PREVIEW_URL + object.getCode(), previewUrl);
//                        }
//                    } catch (Exception ex) {
//                        log.error(ex.getMessage(), ex);
//                        continue;
//                    }
//                }
                String previewUrl;
                try {
                    previewUrl = cameraMonitorService.queryFlvpUrl(object.getCode());
                } catch (Exception ex) {
                    log.error(ex.getMessage(), ex);
                    continue;
                }
                object.setPreviewUrl(previewUrl);
                effectiveList.add(object);
            }
            return DataReturn.ok(effectiveList);
        } catch (Exception e) {
            e.printStackTrace();
            return DataReturn.failure();
        }
    }


    /**
     * 根据父行政区划编码查询子类数量
     * <p>
     * 监控挂在区、县下面，所以区县是叶子节点了。行政区划编码长度是6
     * </p>
     *
     * @param type         监控类型 1防火监控2防盗监控3卡口监控
     * @param online       在线  1在线 0离线
     * @param cameraName   监控名称（模糊查询）
     * @param districtCode 父行政区划编码
     *
     * @return DistrictCountDTO Obj
     */
    @ApiImplicitParams({
            @ApiImplicitParam(name = "type", value = "监控类型 1防火监控2防盗监控3卡口监控", paramType = "query", dataType = "String"),
            @ApiImplicitParam(name = "online", value = "在线  1在线 0离线", paramType = "query", dataType = "String"),
            @ApiImplicitParam(name = "cameraName", value = "监控名称（模糊查询）", paramType = "query", dataType = "String"),
            @ApiImplicitParam(name = "districtCode", value = "行政区划", required = true, paramType = "query", dataType = "String"),
    })
    @GetMapping(value = "/qry-district-list-by-parent-code")
    @ApiOperation(value = "根据父行政区划编码查询子类集合，初始化时请传递省份code（安徽省：34）", httpMethod = Constant.REQUEST_METHOD_GET)
    public DataReturn<DistrictCountDTO> qryDistrictListByParentCode(
            @RequestParam(value = "type", required = false) Integer type,
            @RequestParam(value = "online", required = false) Integer online,
            @RequestParam(value = "cameraName", required = false) String cameraName,
            @RequestParam(value = "districtCode") String districtCode) {
        return DataReturn.ok(cameraInfoService.qryDistrictListByParentCode(type, online, cameraName, districtCode));
    }

    @ApiImplicitParams({
            @ApiImplicitParam(name = "type", value = "监控类型 1防火监控2防盗监控3卡口监控", paramType = "query", dataType = "String"),
            @ApiImplicitParam(name = "online", value = "在线  1在线 0离线", paramType = "query", dataType = "String"),
            @ApiImplicitParam(name = "cameraName", value = "监控名称（模糊查询）", paramType = "query", dataType = "String"),
            @ApiImplicitParam(name = "districtCode", value = "行政区划", required = true, paramType = "query", dataType = "String"),
    })
    @GetMapping(value = "/qry-num-by-parent-code")
    @ApiOperation(value = "根据父行政区划编码查询数量，初始化时请传递省份code（安徽省：34）", httpMethod = Constant.REQUEST_METHOD_GET)
    public DataReturn<DistrictCountDTO> qryNumByParentCode(
            @RequestParam(value = "type", required = false) Integer type,
            @RequestParam(value = "online", required = false) Integer online,
            @RequestParam(value = "cameraName", required = false) String cameraName,
            @RequestParam(value = "districtCode") String districtCode) {
        return DataReturn.ok(cameraInfoService.qryNumByParentCode(type, online, cameraName, districtCode));
    }

    @ApiImplicitParams({
            @ApiImplicitParam(name = "pageNo", value = "当前页数", defaultValue = "1", paramType = "query", dataType = "String"),
            @ApiImplicitParam(name = "pageSize", value = "每页条数", defaultValue = "20", paramType = "query", dataType = "String"),
            @ApiImplicitParam(name = "noPage", value = "是否不分页 true-不分页", paramType = "query", dataType = "String"),
            @ApiImplicitParam(name = "type", value = "监控类型 1防火监控2防盗监控3卡口监控", paramType = "query", dataType = "String"),
            @ApiImplicitParam(name = "online", value = "在线  1在线 0离线", paramType = "query", dataType = "String"),
            @ApiImplicitParam(name = "cameraName", value = "监控名称（模糊查询）", paramType = "query", dataType = "String"),
            @ApiImplicitParam(name = "districtCode", value = "行政区划", required = true, paramType = "query", dataType = "String"),
    })
    @GetMapping(value = "/qry-list-by-parent-code")
    @ApiOperation(value = "分页查询监控列表", httpMethod = Constant.REQUEST_METHOD_GET)
    public DataReturn<PageData<List<CameraVO>>> qryListByParentCode(
            @RequestParam(value = "pageNo", required = false, defaultValue = "1") Integer pageNo,
            @RequestParam(value = "pageSize", required = false, defaultValue = "20") Integer pageSize,
            @RequestParam(value = "noPage", required = false, defaultValue = "false") boolean noPage,
            @RequestParam(value = "type", required = false) Integer type,
            @RequestParam(value = "online", required = false) Integer online,
            @RequestParam(value = "cameraName", required = false) String cameraName,
            @RequestParam(value = "districtCode") String districtCode) {
        return DataReturn.ok(cameraInfoService.qryListByParentCode(pageNo, pageSize, noPage, type, online, cameraName,
                districtCode));
    }

    @GetMapping(value = "/info/{id}")
    @ApiOperation(value = "监控详情", httpMethod = Constant.REQUEST_METHOD_GET)
    public DataReturn<CameraVO> info(@PathVariable(value = "id") String id) {
        return DataReturn.ok(cameraInfoService.info(id));
    }

    @ApiImplicitParams({
            @ApiImplicitParam(name = "id", value = "监控ID（两者不能同时为空）", paramType = "query", dataType = "String"),
            @ApiImplicitParam(name = "code", value = "监控code（两者不能同时为空）", paramType = "query", dataType = "String"),
    })
    @GetMapping(value = "/qry-info")
    @ApiOperation(value = "监控详情2", httpMethod = Constant.REQUEST_METHOD_GET)
    public DataReturn<CameraVO> qryInfo(@RequestParam(value = "id", required = false) String id,
                                        @RequestParam(value = "code", required = false) String code) {
        return DataReturn.ok(cameraInfoService.qryInfo(id, code));
    }

    @PostMapping(value = "/qry-district-list-by-codes")
    @ApiOperation(value = "根据行政区划编码批量查询", httpMethod = Constant.REQUEST_METHOD_POST)
    public DataReturn<DistrictCountDTO> qryDistrictListByCodes(
            QryDistrictListByCodesRequest qryDistrictListByCodesRequest) {
        return DataReturn.ok(cameraInfoService.qryDistrictListByCodes(qryDistrictListByCodesRequest));
    }
//
////    @Deprecated
////    @ApiImplicitParams({
////            @ApiImplicitParam(name = "districtCode", value = "行政区划", required = true, paramType = "query", dataType = "String"),
////            @ApiImplicitParam(name = "fireId", value = "火情id", required = true, paramType = "query", dataType = "String"),
////            @ApiImplicitParam(name = "firePoint", value = "火点信息，例如 point(经纬+纬度)", required = true, paramType = "query", dataType = "String"),
////    })
////    @GetMapping(value = "/qry-camera-list-by-point")
////    @ApiOperation(value = "根据火点信息查询实时视频", httpMethod = Constant.REQUEST_METHOD_GET)
////    public DataReturn<FirePointResourceVO> qryCameraListByPoint(
////            @RequestParam(value = "districtCode") String districtCode,
////            @RequestParam(value = "fireId") String fireId,
////            @RequestParam(value = "firePoint") String firePoint) {
////        return DataReturn.ok(FirePointResourceVO.builder().cameraList(
////                cameraInfoService.qryCameraListByPoint(districtCode, fireId, firePoint)).build());
////    }

    @ApiImplicitParams({
            @ApiImplicitParam(name = "districtCode", value = "行政区划", required = true, paramType = "query", dataType = "String"),
            @ApiImplicitParam(name = "fireId", value = "火情id", required = true, paramType = "query", dataType = "String"),
            @ApiImplicitParam(name = "firePoint", value = "火点信息，例如 point(经纬+纬度)", required = true, paramType = "query", dataType = "String"),
    })
    @GetMapping(value = "/qry-cache-resource-by-point")
    @ApiOperation(value = "根据火点信息查询缓存资源", httpMethod = Constant.REQUEST_METHOD_GET)
    public DataReturn<FirePointResourceVO> qryCacheResourceByPoint(
            @RequestParam(value = "districtCode") String districtCode, @RequestParam(value = "fireId") String fireId,
            @RequestParam(value = "firePoint") String firePoint) {
        return DataReturn.ok(cameraInfoService.qryCacheResourceByPoint(districtCode, fireId, firePoint));
    }

////    @Deprecated
////    @ApiImplicitParams({
////            @ApiImplicitParam(name = "districtCode", value = "行政区划", required = true, paramType = "query", dataType = "String"),
////            @ApiImplicitParam(name = "fireId", value = "火情id", required = true, paramType = "query", dataType = "String"),
////    })
////    @PostMapping(value = "/cache-camera-by-point")
////    @ApiOperation(value = "缓存火场态势首页实时视频", httpMethod = Constant.REQUEST_METHOD_POST)
////    public DataReturn cacheCameraByPoint(@RequestParam(value = "districtCode") String districtCode,
////                                         @RequestParam(value = "fireId") String fireId,
////                                         @RequestBody CameraVO cameraVO) {
////        cameraInfoService.cacheCameraByPoint(districtCode, fireId, cameraVO);
////        return DataReturn.ok();
////    }

    @ApiImplicitParams({
            @ApiImplicitParam(name = "districtCode", value = "行政区划", required = true, paramType = "query", dataType = "String"),
            @ApiImplicitParam(name = "fireId", value = "火情id", required = true, paramType = "query", dataType = "String"),
    })
    @PostMapping(value = "/cache-resource-by-point")
    @ApiOperation(value = "缓存火场态势首页资源", httpMethod = Constant.REQUEST_METHOD_POST)
    public DataReturn cacheResourceByPoint(@RequestParam(value = "districtCode") String districtCode,
                                           @RequestParam(value = "fireId") String fireId,
                                           @RequestBody FirePointResourceVO firePointResourceVO) {
        cameraInfoService.cacheResourceByPoint(districtCode, fireId, firePointResourceVO);
        return DataReturn.ok();
    }

    @ApiImplicitParams({
            @ApiImplicitParam(name = "districtCode", value = "行政区划", required = true, paramType = "query", dataType = "String"),
            @ApiImplicitParam(name = "firePoint", value = "火点信息，例如 point(经纬+纬度)", required = true, paramType = "query", dataType = "String"),
            @ApiImplicitParam(name = "keyWords", value = "搜索关键字", paramType = "query", dataType = "String"),
    })
    @GetMapping(value = "/qry-resource-list-by-point")
    @ApiOperation(value = "根据火点信息查询资源", httpMethod = Constant.REQUEST_METHOD_GET)
    public DataReturn<FirePointResourceVO> qryResourceListByPoint(
            @RequestParam(value = "districtCode") String districtCode,
            @RequestParam(value = "firePoint") String firePoint,
            @RequestParam(value = "keyWords", required = false) String keyWords) {
        return DataReturn.ok(cameraInfoService.qryResourceListByPoint(districtCode, firePoint, keyWords));
    }

    @GetMapping(value = "/queryByCameraIndexCode")
    @ApiOperation(value = "根据火点信息查询资源", httpMethod = Constant.REQUEST_METHOD_GET)
    public DataReturn<CommCameraInfo> queryByCameraIndexCode(
            @RequestParam(value = "cameraIndexCode") String cameraIndexCode) {
        return DataReturn.ok(cameraInfoService.queryByCameraIndexCode(cameraIndexCode));
    }

    @GetMapping("/listByPage")
    @ApiOperation(value = "/资源管理-查询视频监控 不传默认查询全部")
    public DataReturn queryDevice(@RequestParam(required = false) String districtCode,
                                  @RequestParam(required = false) String name,
                                  @RequestParam(required = true) Integer current,
                                  @RequestParam(required = true) Integer size,
                                  @RequestParam(required = false) String monitoringType,
                                  @RequestParam(required = false) String deviceStatus) {
        try {
            PageData<Object> data = cameraInfoService.listByPage(districtCode, monitoringType, name, current, size,
                    deviceStatus);
            return DataReturn.ok(data);
        } catch (Exception e) {
            e.printStackTrace();
            return DataReturn.failure();
        }
    }


    @GetMapping("/queryListByPoint")
    @ApiOperation("根据火点位置查询可视域范围内的监控")
    public DataReturn queryListByPoint(@RequestParam("firePoint") String firePoint, @RequestParam(value = "fireId", required = false) Long fireId,
                                       @RequestParam(value = "flag", required = false) String flag,
                                       @RequestParam(value = "districtCode", required = false) String  districtCode) {
        if (org.springframework.util.StringUtils.isEmpty(firePoint)) {
            return DataReturn.failure(ResultCode.REQUEST_PARAMS_CHECK_ERROR);
        }
        List<CameraFirePointDTO> cameraFirePointDTOList = cameraInfoService.queryListByPoint(firePoint, fireId, districtCode);
        return DataReturn.ok(cameraFirePointDTOList);
    }


    /**
     * 2022-07-08 增加数据权限
     *
     * @param keyWord
     * @param deviceStatus
     * @param monitoringType
     * @param flag           是否属于指挥调度模块,非空代表处于指挥调度
     * @return
     */
    @GetMapping("/queryByCondition")
    @ApiOperation(value = "/条件查询,keyWord关键字 deviceStatus 设备在离线 0离线 1在线 monitoringType1防火监控2防盗监控3卡口监控")
    public DataReturn queryByCondition(@RequestParam(required = false) String keyWord, @RequestParam(required = false) String deviceStatus,
                                       @RequestParam(required = false) String monitoringType, @RequestParam(required = false) String flag,
                                       @RequestParam(value = "districtCode", required = false) String  districtCode) {
        try {
            //fixed by 2022-07-08 ,调整轮询模块
            //当前传入flag 代表 是调度指挥，使用原有districtCode
            //当前不传入flag 代表 不是调度指挥，使用jwt获取的districtCode
            List<CommCameraInfo> list = cameraInfoService.queryByCondition(keyWord, deviceStatus, monitoringType,
                    StrUtil.isNotEmpty(flag) ? StrUtil.EMPTY : districtCode);
            return DataReturn.ok(list);
        } catch (Exception e) {
            e.printStackTrace();
            return DataReturn.failure();
        }
    }

    @PostMapping("/addCamera")
    @ApiOperation("添加监控设备")
    public DataReturn addCamera(@RequestBody CommCameraInfo commonCameraInfo) {
        try {
            if (commonCameraInfo == null) {
                return DataReturn.failure(ResultCode.FORM_PARAMS_CHECK_ERROR);
            }
            cameraInfoService.addCamera(commonCameraInfo);
            return DataReturn.ok();
        } catch (Exception e) {
            e.printStackTrace();
            return DataReturn.failure();
        }
    }

    @GetMapping("/deleteById")
    @ApiOperation("删除监控设备")
    public DataReturn deleteById(@RequestParam List<Long> ids) {
        try {
            if (ids == null) {
                return DataReturn.failure(ResultCode.FORM_PARAMS_CHECK_ERROR);
            }
            cameraInfoService.deleteById(ids);
            return DataReturn.ok();
        } catch (Exception e) {
            e.printStackTrace();
            return DataReturn.failure();
        }
    }

    @PostMapping("/updateById")
    @ApiOperation("修改监控设备")
    public DataReturn updateById(@RequestBody CommCameraInfo commCameraInfo) {
        try {
            if (commCameraInfo == null) {
                return DataReturn.failure(ResultCode.FORM_PARAMS_CHECK_ERROR);
            }
            cameraInfoService.updateById(commCameraInfo);
            return DataReturn.ok();
        } catch (Exception e) {
            e.printStackTrace();
            return DataReturn.failure();
        }
    }

    @GetMapping("/queryById")
    @ApiOperation("根据id查询监控设备信息")
    public DataReturn queryById(@RequestParam Long id) {
        try {
            if (id == null) {
                return DataReturn.failure(ResultCode.FORM_PARAMS_CHECK_ERROR);
            }
            CommCameraInfo commCameraInfo = cameraInfoService.queryById(id);
            return DataReturn.ok(commCameraInfo);
        } catch (Exception e) {
            e.printStackTrace();
            return DataReturn.failure();
        }
    }

}
